ResManager = BaseClass:Extend()
local CSResMgr = CS.ResMgr
local RES_CACHE_TIME = 0

function ResManager:New()
	local o = ResManager.super.New(self)
	--资源引用计数
	o.dic_res_count = {}		--[abName] = num
	o.dic_res_ref = {}		--[self] = {abName}
	o.loading_ab = {}		--正在加载的ab包 加载前占个坑 防止反复走加载逻辑\
	o.dic_cache_ab = {}	--当前页已经加载的ab
	o.loading_wait_handler = {}  --当前等待的加载
	o.loading_wait_spirit_handler = {}  --当前等待的加载
	o:Init()
	return o
end

function ResManager:Init()
	UpdateBeatManager:GetInstance():AddUpdateBeat(self)
end

function ResManager:GetInstance()
	if self.instance == nil then
		self.instance = self:New()
	end
	return self.instance
end

function ResManager:LoadRes(that,abName,resName,level,func)
	CSResMgr.Instance:LoadRes(abName,resName,func,(level or LOAD_LEVEL.FAST))
	self:AddResRef(that,abName)
end

--加载UI/下的资源
function ResManager:LoadSprite(that,img,abName,resName,native,loadfunc)
	if not string.find(abName , "texture") then
		abName = abName .. "_texture"
	end
	local function loaded_callback(obj)
		self:UpdateABResCacheDic(abName,resName,obj)
		obj = CS.Utils.ConvertObjectToSprite(obj)
		self.loading_ab[abName] = false
		if obj then
			if native then
				img:SetNativeSize()
			end
			img.sprite = obj
			if loadfunc then
				loadfunc(obj)
			end
		end
	end

	local cache_obj = self:GetCacheResObj(abName,resName)
	if cache_obj then
		loaded_callback(cache_obj)
	else

		CSResMgr.Instance:LoadSprite(abName,resName,loaded_callback)
		--if not self.loading_ab[abName] then
		--	CSResMgr.Instance:LoadSprite(abName,resName,loaded_callback)
		--	self.loading_ab[abName] = true
		--else
		--	if not self.loading_wait_spirit_handler1[abName] then
		--		self.loading_wait_spirit_handler1[abName] = {func = function(obj)
		--			loaded_callback(obj)
		--		end}
		--	end
		--end
	end
	self:AddResRef(that,abName)
end

--加载Icon/下的资源
function ResManager:LoadOutSideSprite(that,img,module,resName,native,loadfunc)
	if module == nil or module == "" then
		module = "Icon_" .. resName
	else
		module = "Icon_" .. module .. "_" .. resName
	end
	local function loaded_callback(obj)
		self:UpdateABResCacheDic(module,resName,obj)
		obj = CS.Utils.ConvertObjectToSprite(obj)
		self.loading_ab[module] = false
		if obj then
			if native then
				img:SetNativeSize()
			end
			img.sprite = obj
			if loadfunc then
				loadfunc(obj)
			end
		end
	end

	local cache_obj = self:GetCacheResObj(module,resName)
	if cache_obj then
		loaded_callback(cache_obj)
	else
		if not self.loading_ab[module] then
			CSResMgr.Instance:LoadOutSideSprite(module,resName,loaded_callback)
			self.loading_ab[module] = true
		end
	end
	self:AddResRef(that,module)
end

--加载界面预制
function ResManager:CreateView (that,abName,resName,layer,loadUICallback)
	if not string.find(abName,"_prefab") then
		abName = abName .. "_prefab"
	end
	if not self.loading_ab[abName] then
		self.loading_ab[abName] = true
		CS.PanelManager.Instance:CreateView(abName,resName,layer,function(obj)
			self.loading_ab[abName] = false
			loadUICallback(obj)
		end)
	end
	self:AddResRef(that,abName)
end

--加载界面组件
function ResManager:CreateItem (that,abName,resName,loadUICallback)
	if not string.find(abName,"_prefab") then
		abName = abName .. "_prefab"
	end
	if not self.loading_ab[abName] then
		self.loading_ab[abName] = true
		CS.PanelManager.Instance:CreateItem(abName,resName,function(obj)
			self.loading_ab[abName] = false
			if self.loading_wait_handler[abName] and #self.loading_wait_handler[abName] > 0 then
				for i, v in ipairs(self.loading_wait_handler[abName]) do
					v(NewObj(obj))
				end
			end
			self.loading_wait_handler[abName] = false
			loadUICallback(NewObj(obj))
		end)
	else
		self.loading_wait_handler[abName] = self.loading_wait_handler[abName] or {}
		table.insert(self.loading_wait_handler[abName],loadUICallback)
	end
	self:AddResRef(that,abName)
end

--对应引用的计数+1
function ResManager:AddResRef (that,abName)
	self.dic_res_ref[that.__id] = self.dic_res_ref[that.__id] or {}
	if not self.dic_res_ref[that.__id][abName] then
		self.dic_res_count[abName] = self.dic_res_count[abName] and (self.dic_res_count[abName] + 1) or 1
	end
	self.dic_res_ref[that.__id][abName] = true
end

--定时检测销毁
function ResManager:Update(time)
	local curr_time = GetTime()
	for name, vo in pairs(ResManager:GetInstance().dic_cache_ab) do
		if vo.dirty and vo.last_time + RES_CACHE_TIME <= curr_time then
			self:UnloadAB(name)
		end
	end
end

--删除某个实例对应的所有资源引用
function ResManager:ClearAllRef (that)
	local loadedBundles = self.dic_res_ref[that.__id]
	if loadedBundles and next(loadedBundles) then
		for i, v in pairs(loadedBundles) do
			if self.dic_res_count[i] and self.dic_res_count[i] == 1 then
				--CSResMgr.Instance:UnloadRes(i,true)
				self:SetABResDirty(i)		--将AB资源设置成脏
			end
			if self.dic_res_count[i] and self.dic_res_count[i] > 1 then
				self.dic_res_count[i] = self.dic_res_count[i] - 1
			end
		end
	end
	if that.__id and self.dic_res_ref[that.__id] then
		self.dic_res_ref[that.__id] = nil
	end
end

--更新某个资源的使用情况
--dic_cache_ab[abname] = {list={res...} ,last_time , dirty}
function ResManager:UpdateABResCacheDic(ab_name , ab_res , obj)
	if self.dic_cache_ab[ab_name] and self.dic_cache_ab[ab_name].list then
		if not self.dic_cache_ab[ab_name].list[ab_res] then
			self.dic_cache_ab[ab_name].list[ab_res] = obj
		end
		self.dic_cache_ab[ab_name].dirty = false
	else
		self.dic_cache_ab[ab_name] = {list = {[ab_res] = obj} , last_time = GetTime() , dirty = false }
	end
end

function ResManager:GetCacheResObj(ab_name , res_name)
	if self.dic_cache_ab[ab_name] and self.dic_cache_ab[ab_name].list[res_name] then
		return self.dic_cache_ab[ab_name].list[res_name]
	end
end

--将某个ab资源设置成脏标识
function ResManager:SetABResDirty(ab_name)
	if self.dic_cache_ab[ab_name] then
		self.dic_cache_ab[ab_name].dirty = true
		self.dic_cache_ab[ab_name].last_time = GetTime()
	else
		self:UnloadAB(ab_name)
	end
	self.dic_res_count[ab_name] = nil
	if self.loading_ab[ab_name] then
		self.loading_ab[ab_name] = nil
	end
end

function ResManager:UnloadAB(ab_name)
	CSResMgr.Instance:UnloadRes(ab_name,true)
	self.dic_cache_ab[ab_name] = nil
end